package com.apes.fa.service;

import com.alibaba.fastjson.JSONObject;
import com.apes.fa.model.FaAssetInvestItem;
import com.apes.fa.model.FaAssetScrap;
import com.apes.fa.model.FaCard;
import com.apes.fa.model.FaCardAccount;
import com.apes.fa.respository.FaCardAccountRepository;
import com.apes.fa.respository.FaCardRepository;
import com.apes.fico.engine.FicoUtil;
import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.Arith;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.apes.framework.util.ReflectUtil.getMerge;


/**
 * @BelongsProject: apes-server
 * @BelongsPackage: com.apes.fa.service
 * @ClassName: FaCardAccountService
 * @Author: PengZiFeng
 * @Description: 卡片账
 * @CreateTime: 2021-08-25 15:07
 * @Version: 1.0
 */

@Service("faCardAccountService")
public class FaCardAccountService extends DomainService {

    @Autowired
    private FaCardAccountRepository faCardAccountRepository;
    @Autowired
    private FaCardRepository faCardRepository;
    @Autowired
    private DeptRepository deptRepository;

    /**
     * 卡片账
     */
    public FaCardAccount create(FaCardAccount faCardAccount) {
        return faCardAccountRepository.saveAndFlush(faCardAccount);
    }

    /**
     * 生成资产报废卡片账
     */
    public FaCard scrap(FaAssetScrap faAssetScrap, FaCard faCard, SimpleRequest request) {
        faCard.setScrapDate(new Date());
        if (!"(ZCBF)资产报废".equals(faAssetScrap.getBusinessType())) {
            faCard.setFaWhereabouts("报废");
            faCard.setFaStatus("5");
            return faCardRepository.saveAndFlush(faCard);
        }

        double increaseDepreciation = faCard.getOriginalValue() * faCard.getMonthlyDepreciationRate();//本月增加折旧
        double depreciation = 0.0;//折旧
        if (faCard.getDepreciation() == null) {
            depreciation = increaseDepreciation;
        } else {
            depreciation = faCard.getDepreciation() + increaseDepreciation; //折旧
        }
        faCard.setDepreciation(depreciation);
        Integer remainingDepreciationMonth = faCard.getRemainingDepreciationMonth();
        if(remainingDepreciationMonth == null) remainingDepreciationMonth = 0;
        faCard.setRemainingDepreciationMonth(remainingDepreciationMonth - 1);//剩余折旧月
        faCard.setFaWhereabouts("报废");
        faCard.setFaStatus("5");
        faCard.setDepreciationMark(false);

        FaCardAccount faCardAccount = new FaCardAccount();
        faCardAccount.setFaCardId(faCard.getId());
        faCardAccount.setSummary("4");
        faCardAccount.setQuantity(faCard.getQuantity());
        faCardAccount.setOriginalValueIncreased(0.0);
        faCardAccount.setOriginalValueDecrease(0.0);
        faCardAccount.setOriginalValueBalance(faCard.getOriginalValue() - faCard.getDepreciation());//原值余额 = 原值-累计折旧
        if(faCard.isDepreciationMark()){
            faCardAccount.setIncreaseDepreciation(increaseDepreciation);
        }
        faCardAccount.setReduceDepreciation(0.0);
        faCardAccount.setAccumulatedDepreciation(depreciation);
        faCardAccount.setNetWorth(faCard.getOriginalValue() - faCard.getDepreciation());
        faCardAccount.setBookkeeper(this.getPerson(request));
        faCardAccount.setBookkeepingDate(new Date());
        faCardAccount.setCompany(faCard.getCompany());
        Dept dept = deptRepository.findOne(faCard.getDept().getId());
        faCardAccount.setCostCenter(dept.getCostCenterId());
        create(faCardAccount);
        return faCardRepository.saveAndFlush(faCard);

    }

    /**
     * 生成投资转出卡片账
     */
    public FaCard invest(FaCard faCard, SimpleRequest request, FaAssetInvestItem faAssetInvestItem) {

        double increaseDepreciation = faCard.getOriginalValue() * faCard.getMonthlyDepreciationRate();//本月增加折旧
        double depreciation = 0.0;
        if (faCard.getDepreciation() == null) {
            depreciation = increaseDepreciation;
        } else {
            depreciation = faCard.getDepreciation() + increaseDepreciation; //折旧
        }
        faCard.setDepreciation(depreciation);
        faCard.setRemainingDepreciationMonth(faCard.getRemainingDepreciationMonth() - 1);//剩余折旧月
        faCard.setFaWhereabouts("资产转出");
        faCard.setFaStatus("6");
        faCard.setDepreciationMark(false);
        //资产转出后修改成本中心和公司
        //faCard.setUseDept(faAssetInvestItem.getInCostCenter());
        //faCard.setCompany(faAssetInvestItem.getInCostCenter().getCompany());

        FaCardAccount faCardAccount = new FaCardAccount();
        faCardAccount.setFaCardId(faCard.getId());
        faCardAccount.setSummary("5");
        faCardAccount.setQuantity(faCard.getQuantity());
        faCardAccount.setOriginalValueIncreased(0.0);
        faCardAccount.setOriginalValueDecrease(0.0);
        faCardAccount.setOriginalValueBalance(faCard.getOriginalValue() - faCard.getDepreciation());//原值余额 = 原值-累计折旧
        faCardAccount.setIncreaseDepreciation(increaseDepreciation);
        faCardAccount.setReduceDepreciation(0.0);
        faCardAccount.setAccumulatedDepreciation(depreciation);
        faCardAccount.setNetWorth(faCard.getOriginalValue() - faCard.getDepreciation());
        faCardAccount.setBookkeeper(this.getPerson(request));
        faCardAccount.setBookkeepingDate(new Date());
        Dept dept = deptRepository.findOne(faCard.getDept().getId());
        faCardAccount.setCostCenter(dept.getCostCenterId());
        create(faCardAccount);
        return faCardRepository.saveAndFlush(faCard);

    }

    /**
     * 生成盘亏卡片账
     */
    public FaCard inventoryLoss(FaCard faCard, SimpleRequest request) {
        if("固定资产".equals(faCard.getFaType())){
        double increaseDepreciation = faCard.getOriginalValue() * faCard.getMonthlyDepreciationRate();//本月增加折旧
        double depreciation = 0.0;
        if (faCard.getDepreciation() == null) {
            depreciation = increaseDepreciation;
        } else {
            depreciation = faCard.getDepreciation() + increaseDepreciation; //折旧
        }
        faCard.setDepreciation(depreciation);
        faCard.setRemainingDepreciationMonth(faCard.getRemainingDepreciationMonth() - 1);//剩余折旧月
        faCard.setFaWhereabouts("盘亏");
        faCard.setFaStatus("8");
        faCard.setDepreciationMark(false);

        FaCardAccount faCardAccount = new FaCardAccount();
        faCardAccount.setCompany(faCard.getCompany());
        Dept dept = deptRepository.findOne(faCard.getDept().getId());
        faCardAccount.setCostCenter(dept.getCostCenterId());
        faCardAccount.setFaCardId(faCard.getId());
        faCardAccount.setSummary("3");
        faCardAccount.setQuantity(faCard.getQuantity());
        faCardAccount.setOriginalValueIncreased(0.0);
        faCardAccount.setOriginalValueDecrease(faCard.getOriginalValue() - faCard.getDepreciation());
        faCardAccount.setOriginalValueBalance(0.0);//原值余额 = 原值-累计折旧
        faCardAccount.setIncreaseDepreciation(increaseDepreciation);
        faCardAccount.setReduceDepreciation(0.0);
        faCardAccount.setAccumulatedDepreciation(Arith.round(depreciation,2));
        faCardAccount.setNetWorth(0.0);
        faCardAccount.setBookkeeper(this.getPerson(request));
        faCardAccount.setBookkeepingDate(new Date());
        create(faCardAccount);
        }else{
            faCard.setFaWhereabouts("盘亏");
            faCard.setFaStatus("8");
        }
        return faCardRepository.saveAndFlush(faCard);

    }


    /**
     * 生成提取折旧卡片账
     */
    public FaCard withdrawDepreciationCard(FaCard faCard, SimpleRequest request) {
        if(faCard.getRemainingDepreciationMonth() != 0){
            double increaseDepreciation = faCard.getOriginalValue() * faCard.getMonthlyDepreciationRate();//本月增加折旧
            if(faCard.getOriginalValue() - faCard.getDepreciation() < increaseDepreciation) throw new RuntimeException("卡片："+faCard.getId()+" 折旧金额大于剩余可折旧金额,请检查");
            //保留两位小数
            BigDecimal bigDecimal = new BigDecimal(increaseDepreciation);
            double increaseDepreciationNew = bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
            double depreciation;
            if (faCard.getDepreciation() == null) {
                depreciation = increaseDepreciationNew;
            } else {
                depreciation = faCard.getDepreciation() + increaseDepreciationNew; //折旧
            }
            faCard.setDepreciation(depreciation);
            faCard.setRemainingDepreciationMonth(faCard.getRemainingDepreciationMonth() - 1);//剩余折旧月
            FaCardAccount faCardAccount = new FaCardAccount();
            faCardAccount.setFaCardId(faCard.getId());
            faCardAccount.setSummary("2");
            faCardAccount.setQuantity(faCard.getQuantity());
            faCardAccount.setOriginalValueIncreased(0.0);
            faCardAccount.setOriginalValueDecrease(0.0);
            faCardAccount.setOriginalValueBalance(faCard.getOriginalValue() - faCard.getDepreciation());//原值余额 = 原值-累计折旧
            faCardAccount.setIncreaseDepreciation(increaseDepreciationNew);
            faCardAccount.setReduceDepreciation(0.0);
            faCardAccount.setAccumulatedDepreciation(depreciation);
            faCardAccount.setNetWorth(faCard.getOriginalValue() - faCard.getDepreciation());
            faCardAccount.setBookkeeper(this.getPerson(request));
            JSONObject month = (JSONObject) request.get("MONTH");
            Calendar ca = Calendar.getInstance();
            ca.set(Calendar.MONTH,Integer.parseInt(month.getString("id")) -1);
            ca.set(Calendar.DAY_OF_MONTH,ca.getActualMaximum(Calendar.DAY_OF_MONTH));
            Date firstDate = ca.getTime();
            faCardAccount.setBookkeepingDate(firstDate);
            faCardAccount.setCompany(faCard.getCompany());
            Dept dept = deptRepository.findOne(faCard.getDept().getId());
            if(dept.getCostCenterId() == null) throw new RuntimeException("资产卡片: " + faCard.getId() + " 的部门: " + dept.getId() + "没有成本中心,请配置后重试");
            faCardAccount.setCostCenter(dept.getCostCenterId());
            create(faCardAccount);
            faCard = faCardRepository.saveAndFlush(faCard);
        }
        return faCard;
    }
//    /**
//     * 提取折旧
//     */
//    public double withdrawDepreciation(FaCard faCard){
//
//        if(faCard.getRemainingDepreciationMonth() == 1){
//
//        }
//        double increaseDepreciation = faCard.getOriginalValue() * faCard.getMonthlyDepreciationRate();//本月增加折旧
//
//    }


    /**
     * 解析折旧表达式
     */
    public FaCard depreciationExpression(FaCard faCard) {

        //解析折旧表达式
        String express = faCard.getDepreciationMethod().getAmountformula();
        Number number = FicoUtil.eval(express, getMerge(faCard), 0.0, true, Throwable::getMessage);
        double monthDepRate = number.doubleValue();
        double yearDepRate = monthDepRate * 12;
        BigDecimal monthDepRateBD = new BigDecimal(monthDepRate);
        BigDecimal yearDepRateBD = new BigDecimal(yearDepRate);
        faCard.setMonthlyDepreciationRate(monthDepRateBD.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue());
        faCard.setAnnualDepreciationRate(yearDepRateBD.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue());
        return faCard;

    }

    /**
     * 根据卡片Id查全部
     */
    public List<FaCardAccount> findAll(SimpleRequest request) {

        String id = request.get("id");
        List<FaCardAccount> faCardAccounts = faCardAccountRepository.findAllByFaCardId(id);
        return faCardAccounts;

    }

    /**
     * 按月收集资产卡片账到门店经营成本
     * @param request
     */
    private void findFaCardAccountByMonth(SimpleRequest request){
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH,-1);
        Date date = c.getTime();
        String months = DateUtil.format(date, "MM");
        String years = DateUtil.format(date, "YYYY");
        List<Map<String, Object>> faCardAccountMapList = faCardAccountRepository.findAllByYearMonth(months, years);
        faCardAccountMapList.stream().forEach(map -> this.invoke("finance.operatingCosts.costAccumulation", MapUtil.mapper("amt",map.get("ZJJE"), "state","actually",
                "yearMonth",DateUtil.format(date, "yyyy-MM-dd"), "dept",map.get("deptId"),
                "company",deptRepository.findOne(map.get("deptId").toString()).getCompany().getId(),"typeCost","15", "costType","002107",
                "sourceReceipt","资产折旧")));
    }

    private void findByDate(SimpleRequest request){
        String companyId = request.get("companyId").toString();
        String periodDate = request.get("periodDate").toString();
        List<FaCard> faCards = faCardRepository.findFaCardByCarryOverPL(companyId, "固定资产", periodDate, 1);
        if(faCards.isEmpty()) return;
        List<FaCard> faCardAccount = faCardRepository.findByCarryOverPL(companyId, "固定资产", periodDate, 1);
        if(faCardAccount.isEmpty()) throw new RuntimeException("该月还未折旧,无法月结");
    }

}
